package com.ljx.comprehensiveCase.framework.context.support;

import com.ljx.comprehensiveCase.framework.beans.BeanDefinition;
import com.ljx.comprehensiveCase.framework.beans.factory.support.BeanDefinitionReader;
import com.ljx.comprehensiveCase.framework.beans.factory.support.BeanDefinitionRegistry;
import com.ljx.comprehensiveCase.framework.context.ApplicationContext;
import lombok.Data;

import java.util.HashMap;
import java.util.Map;

/**
 *
 * 作为ApplicationContext接口的子类，所以该类也是非延时加载，所以需要在该类中定义一个Map集合，作为bean对象存储的容器
 *
 * 声明BeanDefinitionReader类型的变量，用来进行xml配置文件的解析，符合单一职责原则。
 * BeanDefinitionReader类型的对象创建交由子类实现，因为只有子类明确到底创建BeanDefinitionReader哪儿个子实现类对象
 *
 * @作者 LJX
 * @日期 2022/12/27 17:06
 */
public abstract class AbstractApplicationContext implements ApplicationContext {

    protected BeanDefinitionReader beanDefinitionReader;

    //用来存储bean对象的容器   key存储的是bean的id值，value存储的是bean对象
    protected Map<String, Object> singletonObjects = new HashMap<>();

    //存储配置文件的路径
    protected String configLocation;

    @Override
    public void refresh() throws Exception {
        //加载BeanDefinition
        beanDefinitionReader.loadBeanDefinitions(configLocation);

        //初始化bean
        finishBeanInitialization();

    }

    /**
     * 初始化bean
     *
     * finishBeanInitialization()方法中调用getBean()方法使用到了模板方法模式
     *
     * @throws Exception
     */
    private void finishBeanInitialization() throws Exception {
        BeanDefinitionRegistry registry = beanDefinitionReader.getRegistry();

        String[] beanDefinitionNames = registry.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            BeanDefinition beanDefinition = registry.getBeanDefinition(beanDefinitionName);
            getBean(beanDefinitionName);
        }
    }
}
